package org.iris.plugin

import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors
import net.mamoe.mirai.console.permission.PermissionId
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.testPermission
import net.mamoe.mirai.console.permission.PermitteeId.Companion.permitteeId
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
import net.mamoe.mirai.contact.Contact.Companion.sendImage
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.User
import net.mamoe.mirai.contact.getMember
import net.mamoe.mirai.contact.getMemberOrFail
import net.mamoe.mirai.event.events.MessageEvent
import net.mamoe.mirai.event.globalEventChannel
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.content
import net.mamoe.mirai.message.data.firstIsInstance
import net.mamoe.mirai.message.data.time
import net.mamoe.mirai.utils.info
import org.iris.plugin.command.AddAlias
import org.iris.plugin.command.ClearCache
import org.iris.plugin.config.HitHitConfig
import org.iris.plugin.data.HitHitData
import org.iris.plugin.model.*
import org.iris.plugin.model.Tools.getUserOrNull
import org.iris.plugin.util.AutoClear
import org.iris.plugin.util.inActive
import java.util.*

@OptIn(ConsoleExperimentalApi::class, ExperimentalCommandDescriptors::class)
object HitHit : KotlinPlugin(
    JvmPluginDescription(
        id = "org.iris.plugin.hithit",
        name = "HitHit",
        version = "2.0.1",
    )
) {

    val tmp = dataFolder.resolve("tmp")
    private val hitPerm = PermissionId(HitHit.description.id, "hit")
    val ColddownTemp = mutableMapOf<String, Int>()


    override fun onEnable() {
        val osName = System.getProperties().getProperty("os.name")
        if (!osName.startsWith("Windows")) {
            logger.info { "检测到当前为${osName}系统，将使用headless模式" }
            System.setProperty("java.awt.headless", "true")
        }
        init()
        logger.info { "锤人插件已加载" }
        PermissionService.INSTANCE.register(hitPerm, "Hit@某人")

        globalEventChannel().subscribeAlways<MessageEvent> {

            val action = getAction(message.content)
            if (action == Action.NONE || !ENABLE_MAP[action]!!) {
                return@subscribeAlways
            }

            // 权限控制
            if (subject is User && !hitPerm.testPermission((subject as User).permitteeId)) {
                logger.info { "没有权限 ${sender.permitteeId}" }
                return@subscribeAlways
            }
            if (subject is Group && ! hitPerm.testPermission((subject as Group).getMemberOrFail(sender.id).permitteeId)) {
                logger.info { "没有权限 ${(subject as Group).getMemberOrFail(sender.id).permitteeId}" }
                return@subscribeAlways
            }

            // 锤人CD，防止刷屏，CD可以不同群分别设置
            val needColddown = subject is Group && subject.id.toString() in HitHitConfig.Colddown.keys
            if (needColddown) {
                if (subject.id.toString() in ColddownTemp.keys && message.time - ColddownTemp[subject.id.toString()]!! < HitHitConfig.Colddown[subject.id.toString()]!!) {
                    logger.info {"[${(subject as Group).name}(${(subject as Group).id})]冷却时间剩余${HitHitConfig.Colddown[subject.id.toString()]!! - (message.time - ColddownTemp[subject.id.toString()]!!)}秒"}
                    return@subscribeAlways
                }
            }

            if (message.contains(Image)) {
                runCatching {
                    val image = message.firstIsInstance<Image>()
                    HitHitTool.getImage(action, sender, image, DELAY_MAP[action]!!)
                    subject.sendImage(tmp.resolve("${sender.id}_${image.imageId}_${action}.gif"))
                }.onFailure { e -> logger.error(e) }
                return@subscribeAlways
            }

            var content = message.content
            for (word in WORD_MAP[action]!!) {
                content = content.replace(word, "")
            }
            if (content.isEmpty()) {
//                subject.sendMessage("发送${message.content}+@来${message.content}其他人喵")
                return@subscribeAlways
            }
            var fast = false
            if (content[0] == '爆') {
                content = content.substring(1, content.length)
                fast = true
            }
            val name = subject.id.toString() + "_" + content
            val targetId = when {
                content == "我" ->
                    null
                HitHitData.alias.containsKey(name) ->
                    HitHitData.alias[name].toString()
                else -> content
            }
            var target =
                if (targetId == null) sender else subject.getUserOrNull(targetId) ?: run { return@subscribeAlways }
//            subject.sendMessage("不知道要${WORD_MAP[action]!!.first()}谁喵").

            // 锤自己的话由bot来锤喵
            var send = if (target == sender) bot else sender

            // 不能锤bot owner
            if (target.id in HitHitData.botOwner && send != bot) {
                send = target
                target = sender
            }

            if (fast) {
                val image = tmp.resolve("${send.id}_${target.id}_${action}.gif")
                if (image.exists()) image.delete()
                HitHitTool.getAction(action, send, target, DELAY_MAP[action]!! / 2)
                subject.sendImage(image)
                image.delete()
            }
            else {
                HitHitTool.getAction(action, send, target, DELAY_MAP[action]!!)
                subject.sendImage(tmp.resolve("${send.id}_${target.id}_${action}.gif"))
            }

            if (inActive.add("${send.id}_${target.id}_${action}.gif")) {
                val task = AutoClear("${send.id}_${target.id}_${action}.gif")
                Timer().schedule(task, Date(System.currentTimeMillis() + 2 * 60 * 1000))
            }

            // 重置锤人CD
            if (needColddown) {
                    ColddownTemp[subject.id.toString()] = message.time
            }
        }
    }

    override fun onDisable() {
        logger.info { "锤人插件已卸载" }
    }

    private fun init() {
        ClearCache.register()
        AddAlias.register()
        HitHitData.reload()
        HitHitConfig.reload()
        if (tmp.exists()) tmp.deleteRecursively()
        if (!tmp.exists()) tmp.mkdir()
        logger.info { "缓存已自动清理" }
    }


    private fun getAction(msg: String) : Action {
        for (pair in WORD_MAP) {
            for (word in pair.value) {
                if (msg.startsWith(word)) {
                    return pair.key
                }
            }
        }
        return Action.NONE
    }
}